package com.algorithms.arrays;

import com.algorithms.utils.AlgorithmException;

/**
 * this Queue bases on Ring-Buffer data structure. the queue maintains
 * 2 pointers 
 *  - front: where item is pop out
 *  - rear: 
 * 
 * @author minhld
 *
 * @param <T>
 */
public class Queue<T> extends AbstractArray<T> {
	private int rear = INVALID_INDEX;
	private int front = 0;

	public Queue(int maxElementCount) {
		super(maxElementCount);
	}
	
	@Override
	public T pop() throws AlgorithmException {
		if (isEmpty()){
			throw new AlgorithmException("queue is empty.");
		}else{
			T ret = this.data[front];
			if (front == this.maxElementCount - 1){
				front = 0;
			}else{
				front++;
			}
			
			this.length--;
			
			return ret;
		}
	}

	@Override
	public void push(T value) throws AlgorithmException {
		if (isFull()){
			throw new AlgorithmException("queue is full.");
		}else{
			if (rear == this.maxElementCount - 1){
				rear = INVALID_INDEX;
			}
			this.data[++rear] = value;
			this.length++;
		}
	}

	@Override
	public T peak() {
		return this.data[front];
	}

	@Override
	public boolean isEmpty() {
		return this.length == 0;
	}
	
	@Override
	public boolean isFull() {
		return this.length == this.maxElementCount;
	}
	
}
